#include <windows.h>
#include <tchar.h>
#include <commdlg.h>

#include <stdlib.h>
#include <string.h>

#include "lib.h"
#include "update.h"
#include "pkgdesc.h"
#include "resids.h"

#define SELF	UpdateDlg
#define SUPER	SyncDialog

UpdateDlg::UpdateDlg(HINSTANCE hInst, HWND hParent, Mode mode,
	PackageDescription* Pkg)
	: SyncDialog(hParent, hInst)
{
	cMode = mode;
	cPkg = Pkg;
	hZipName = hName = hVersion = (HWND)0;
	cNameTyped = false;
}

int
UpdateDlg::Run(void)
{
	hDialog = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_PKGCHANGE), hParent,
		(DLGPROC)topDialogProc, (LPARAM)this);

	return SUPER::Run();
}

void
UpdateDlg::Init()
{
	switch (cMode)
	{
		case ADD:
			SendMessage(hDialog, WM_SETTEXT, 0, (LPARAM)"Add package");
			break;

		case UPDATE:
			SendMessage(hDialog, WM_SETTEXT, 0, (LPARAM)"Update package");
			break;
	}

	hZipName = GetDlgItem(hDialog, IDC_FILENAME);
	hName = GetDlgItem(hDialog, IDC_NAME);
	hVersion = GetDlgItem(hDialog, IDC_VERSION);

	SendMessage(hZipName, EM_SETLIMITTEXT, MAX_PATH, 0);

	TransferToDlg(cPkg);

	SendMessage(hZipName, EM_SETSEL, 0, (LPARAM)-1);

	EnableWindow(GetDlgItem(hDialog, IDOK), FALSE);
}

void
UpdateDlg::TransferToDlg(PackageDescription* desc)
{
	if (desc->getZipName())
	{
		SendMessage(hZipName, WM_SETTEXT, 0, (LPARAM)(const uint16*)desc->getZipName());
		cNameTyped = false;
	}

	if (desc->getName())
		SendMessage(hName, WM_SETTEXT, 0, (LPARAM)(const uint16*)desc->getName());

	if (desc->getVersion())
	{
		TCHAR text[256];

		wsprintf(text, L"%d.%d",
			HIWORD(desc->getVersion()), LOWORD(desc->getVersion()));

		SendMessage(hVersion, WM_SETTEXT, 0, (LPARAM)text);
	}
}

bool8
UpdateDlg::TransferFromDlg()
{
	char buf[1024];
	int32 len;

	len = SendMessage(hZipName, WM_GETTEXT, 1024, (LPARAM)buf);
	buf[len] = '\0';

	return cPkg->setZipFile(buf);
}

bool8
UpdateDlg::Validate(PackageDescription* desc)
{
	if (cMode == UPDATE)
		return (bool8)(
			0 == desc->getName().caseCompare(cPkg->getName()) &&
			desc->getVersion() != cPkg->getVersion());

	return true;
}

void
UpdateDlg::ManualFilename(WORD code)
{
	switch (code)
	{
		case EN_SETFOCUS:
			cNameTyped = false;
			break;
		case EN_CHANGE:
			cNameTyped = true;
			break;
		case EN_KILLFOCUS:
			if (cNameTyped)
			{
				char buf[1024];
				int32 len;
				PackageDescription test;

				len = SendMessage(hZipName, WM_GETTEXT, 1024, (LPARAM)buf);
				buf[len] = '\0';

				if (test.setZipFile(buf))
				{
					if (Validate(&test))
					{
						TransferToDlg(&test);
						EnableWindow(GetDlgItem(hDialog, IDOK), TRUE);
					}
					else
					{
						MessageBox(hDialog, _T("That is not a valid update for ")
							_T("this Casino Client Package."), _T("Error"),
							MB_ICONERROR | MB_OK);

						TransferToDlg(cPkg);
						EnableWindow(GetDlgItem(hDialog, IDOK), FALSE);
					}
				}
				else
				{
					MessageBox(hDialog, _T("Invalid Casino Client Package."),
						_T("Error"), MB_ICONERROR | MB_OK);

					TransferToDlg(cPkg);
					SendMessage(hZipName, EM_SETSEL, 0, (LPARAM)-1);
					SetFocus(hZipName);
				}
				break;
			}
			break;
	}
}

void
UpdateDlg::Browse()
{
	OPENFILENAME ofn;
	TCHAR filename[MAX_PATH];
	int32 len;

	len = SendMessage(hZipName, WM_GETTEXT, MAX_PATH, (LPARAM)filename);
	filename[len] = '\0';

	ZeroMemory(&ofn, sizeof(OPENFILENAME));
	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hwndOwner = hDialog;
	ofn.lpstrFilter = _T("Casino Client Packages\0*.zip\0\0");
	ofn.lpstrFile = filename;
	ofn.nMaxFile = MAX_PATH;
	ofn.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | OFN_NONETWORKBUTTON |
		OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;

	if (GetOpenFileName(&ofn))
	{
		PackageDescription test;

		if (test.setZipFile(filename))
		{
			if (Validate(&test))
			{
				TransferToDlg(&test);
				EnableWindow(GetDlgItem(hDialog, IDOK), TRUE);
			}
			else
				MessageBox(hDialog, _T("That is not a valid update for this")
					_T(" Casino Client Package."), _T("Error"),
					MB_ICONERROR | MB_OK);
		}
		else
			MessageBox(hDialog, _T("Invalid Casino Client Package."),
				_T("Error"), MB_ICONERROR | MB_OK);
	}
}

BOOL
UpdateDlg::dialogProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
	{
		case WM_INITDIALOG:
			Init();
			return FALSE;

		case WM_COMMAND:
			switch (LOWORD(wParam))
			{
				case IDCANCEL:
					EndDialog(hWnd, LOWORD(wParam));
					return TRUE;

				case IDOK:
					if (TransferFromDlg())
						EndDialog(hWnd, LOWORD(wParam));
					else
					{
						MessageBox(hWnd, _T("Memory problem...update ignored."),
							_T("Error"), MB_ICONERROR | MB_OK);

						EndDialog(hWnd, IDCANCEL);
					}
					return TRUE;

				case IDC_BROWSE:
					Browse();
					break;

				case IDC_FILENAME:
					ManualFilename(HIWORD(wParam));
					break;
			}
			break;
	}

	return SUPER::dialogProc(hWnd, Msg, wParam, lParam);
}
